// 一 请说出下列的最终执行结果，并解释为什么。
// var a = []
// for (var i = 0; i < 10; i++) {
//   a[i] = function () {
//     console.log(i)
//   }
// }

// a[6]() 

// 解：10
// 1 首先for循环中的i，用var定义的是全局变量，每次循环的i++都是全局变量i在改变，
//   当循环结束的时候，数组里存的10个函数，打印的i也都是同一个全局i，所以打印出来的是10
// 解决方式可以使用使之能成为块级作用域的let，或者通过自调用函数+闭包的方式




// 二 请说出下列的最终执行结果，并解释为什么。
// var tmp = 123;
// if(true){
//   console.log(tmp)
//   let tmp
// }
// 解：
// 会报错，let定义tmp会形成暂时性死区，此模块内的变量tmp通过let定义了，但是let不存在变量提升，因此在tmp定义之前打印tmp会报错





// 三 结合es6新语法，用最简单的方式找出数组中的最小值
// var arr = [12, 34, 32, 89, 4]
// 解：
// 1 从小到大排序，取第一个值
// var min = arr.sort((a, b) => {
//   return a - b
// })[0];
// 2 借用Math.min+扩展运算符
// var min = Math.min(...arr);
// 3 借用Math.min
// var min = Math.min.apply(null, arr)




// 四 请详细说吗var let const的区别
// 解：
// 1 let声明的变量拥有块级作用域,const有，var没有
// 2 let声明的全局变量不是全局对象的属性,window.变量名的方式取不到值，它们只存在于一个不可见的块的作用域中，这个块理论上是Web页面中运行的所有JS代码的外层块。
// 而var是全局对象的属性
// 3 let重定义会抛出语法错误
// 4 const是用来定义常量的




// 五 请说出下列代码最终输出结果，并结束为什么
// var a = 10
// var obj = {
//   a:20,
//   fn(){
//     setTimeout(()=>{
//       console.log(this.a)
//     })
//   }
// }
// obj.fn()
// 解：20
// 箭头函数自己没有this，它的this指向最近一级的作用域的上下文，也就是fn的调用上下文，即：obj，obj.a为20




// 六 简述Symbol类型的用途
// 解：
// ES5 的对象属性名都是字符串，这容易造成属性名的冲突。比如，你使用了一个他人提供的对象，但又想为这个对象添加新的方法（mixin 模式），
// 新方法的名字就有可能与现有方法产生冲突。如果有一种机制，保证每个属性的名字都是独一无二的就好了，这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol的原因




// 七 说说什么是浅拷贝，什么是深拷贝
// 解：
// 1 浅拷贝只能复制对象的第一层属性，如若第一层属性值也是对象，或更深层级的，浅拷贝拷贝的就是引用地址
// 2 深拷贝是完完全全复制了原对象的所有属性和值




// 八 请简述Typescrip和JavaScript的关系
// 解：
// 1 typescript是JavaScript的超集
// 2 JavaScript没有类型约束，typescript有
// 3 类型系统按照类型检查的时机：typescript是静态类型（编译时），JavaScript 是一门解释型语言，没有编译阶段，是动态类型（运行时）
// 4 类型系统按照「是否允许隐式类型转换」来分类，可以分为强类型和弱类型。typescript和JavaScript都是弱类型
// 5 TypeScript 可以编译为 JavaScript，然后运行在浏览器、Node.js 等任何能运行 JavaScript 的环境中。




// 九 请谈谈你所认为的typescript的优缺点

// 优点：
// 1 TypeScript 增加了代码的可读性和可维护性
//    a 类型系统实际上是最好的文档，大部分的函数看看类型的定义就可以知道如何使用了
//    b 可以在编译阶段就发现大部分错误，这总比在运行时候出错好
//    c 增强了编辑器和 IDE 的功能，包括代码补全、接口提示、跳转到定义、重构等
// 2 TypeScript 非常包容
//    a TypeScript 是 JavaScript 的超集，.js 文件可以直接重命名为 .ts 即可
//    b 即使不显式的定义类型，也能够自动做出[类型推论]()
//    c 可以定义从简单到复杂的几乎一切类型
//    d 即使 TypeScript 编译报错，也可以生成 JavaScript 文件
//    e 兼容第三方库，即使第三方库不是用 TypeScript 写的，也可以编写单独的类型文件供 TypeScript 读取
// 3 TypeScript 拥有活跃的社区
//    a 大部分第三方库都有提供给 TypeScript 的类型定义文件
//    b Google 开发的 Angular2 就是使用 TypeScript 编写的
//    c TypeScript 拥抱了 ES6 规范，也支持部分 ESNext 草案的规范

// 缺点
// 1 有一定的学习成本，需要理解接口（Interfaces）、泛型（Generics）、类（Classes）、枚举类型（Enums）等前端工程师可能不是很熟悉的概念
// 2 短期可能会增加一些开发成本，毕竟要多写一些类型的定义，不过对于一个需要长期维护的项目，TypeScript 能够减少其维护成本
// 3 集成到构建流程需要一些工作量
// 4 可能和一些库结合的不是很完美




// 十 描述引用计数的工作原理和优缺点

// 工作原理：
// 对每个对象保存一个整型的引用计数属性，用于记录对象被引用的情况。对于一个对象A，只有当其被引用一次，则A的引用计数器+1，当引用失效时，
// 则-1，只要对象的引用计数属性为0时，则表示A对象没有再被使用，可进行回收

// 优缺点
// 优点：实现简单，垃圾对象便于辨识；判定效率高，回收没有延迟性。
// 缺点：
//     1 他需要单独的字段存储计数器，这样的做法增加了存储空间的开销
//     2 每次赋值都需要更新计数器，伴随着加法和减法操作，这增加了时间开销
//     3 无法处理循环引用的问题




// 十一 描述标记整理算法的工作流程
// 1 标记整理可以看成是标记清除的增强,也分标记阶段和清除阶段
// 2 标记阶段的操作和标记清除一样
//   a 遍历所有可达对象，标记活动对象
// 3 清除阶段会先执行整理，移动对象位置，使其在地址上连续，解决碎片化
//   a 遍历所有对象，清除没有被标记对象
//   b 回收相应空间




// 十二 描述V8中新生代存储区的垃圾回收的流程
// 1 回收过程采用复制算法+标记整理
// 2 新生代回收区分为大小相等的两个区：from,to
// 3 使用空间为from，空闲空间为to
// 4 活动对象存储在from空间
// 5 标记整理后将活动对象拷贝至to空间
// 6 from与to交换空间完成释放




// 十三 描述增量标记算法在何时使用及工作原理
// 没看到有课程说这个？

